博客测试的数据库是之前已经创建好的,一个模拟jing_dong的数据库,在此基础上进行的测试。
1.python查询数据库内容
from pymysql import connect
def query():
"""查询数据"""
# 创建connection连接
conn = connect(host="localhost",port=3306,user="root",password="0118",database="jing_dong",charset="utf8")
# 获得cursor对象
cur = conn.cursor()
# 执行select语句,并返回受影响的行数:查询一条数据
count = cur.execute("select * from goods")
# 打印受影响的行数
print("查询到%d条数据:" % count)
# 单行查询
# lines_data = cur.fetchone() # 每次只查询一条数据
# 多行查询
# lines_data = cur.fetchmany(10) # 查询十条数据
# 所有数据查询
result = cur.fetchall()
print(result)
cur.close()
conn.close()
if __name__ == '__main__':
query() # 查询
# modify() # 修改
2.python修改(增删改)数据库内容
修改数据需要执行commit操作,这是与查询不同的地方,只有提交之后数据才能生效。
def modify():
"""增加,删除,修改数据需要提交操作,得到允许后修改的数据才生效"""
# 创建connection连接
conn = connect(host="localhost",port=3306,user="root",password="0328",database="jing_dong",charset="utf8")
# 获得cursor对象
cur = conn.cursor()
# 执行select语句,并返回受影响的行数:查询一条数据
count = cur.execute('insert into goods_cates(name) values("硬盘")')
# 打印受影响的行数
print("查询到%d条数据:" % count)
# 修改
count = cur.execute('update goods_cates set name="机械硬盘" where name="硬盘"')
# 删除
# count = cur.execute('delete from goods_cates where id="6"')
# 提交之前的操作,如果之前已经之执行过多次的execute,那么就都进行提交
conn.commit()
# 撤回之前的操作
# cur.rollback()
# 关闭Cursor对象
cur.close()
# 关闭connection对象
conn.close()
if __name__ == '__main__':
modify() # 修改
3.使用面向对象的方式访问数据库
from pymysql import connect
class JD(object):
"""docstring for ClassName"""
def __init__(self):
# 创建connection连接
self.conn = connect(host="localhost",port=3306,user="root",password="0118",database="jing_dong",charset="utf8")
# 获得cursor对象
self.cur = self.conn.cursor()
def __delete__(self):
self.cur.close()
self.conn.close()
def execute_sql(self,sql):
# 执行select语句,并返回受影响的行数:查询一条数据
self.cur.execute(sql)
for temp in self.cur.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 add_cates(self):
item_name = input("请输入新商品名称:")
sql = 'insert into goods_cates(name) values ("%s")' % item_name
self.cur.execute(sql)
self.conn.commit()
def print_menu(self):
"""功能选择"""
print("1.所有的商品")
print("2.所有的商品分类")
print("3.所有的商品品牌分类")
print("4.添加商品分类")
num = input("请输入功能对应的序号:")
return num
def run(self):
while True:
num = self.print_menu()
if num == "1":
# 查询所有的商品
self.show_all_items()
elif num=="2":
# 查询分类
self.show_cates()
elif num == "3":
# 查询品牌分类
self.show_brands()
elif num == "4":
# 查询品牌分类
self.add_cates()
else:
print("输入有误,请重新输入...")
def main():
# 创建实例对象
jd = JD()
# 执行run方法
jd.run()
if __name__ == '__main__':
main()
4.防止SQL注入
- sql语句的参数化,可以有效防止sql注入
- 注意:此处不同于python的字符串格式化,全部使用%s占位
这里说的比较简单,sql注入就是通过特别的输入,获取你数据库的数据。
sql = 'select * from goods where name="%s"' % find_name
# 类似输入 " or 1=1 or " (双引号也要输入),通过字符串自己匹配会出现bug,可以进入数据库获取全部数据
from pymysql import connect
class JD(object):
"""docstring for ClassName"""
def __init__(self):
# 创建connection连接
self.conn = connect(host="localhost",port=3306,user="root",password="0328",database="jing_dong",charset="utf8")
# 获得cursor对象
self.cur = self.conn.cursor()
def __delete__(self):
self.cur.close()
self.conn.close()
def execute_sql(self,sql):
# 执行select语句,并返回受影响的行数:查询一条数据
self.cur.execute(sql)
for temp in self.cur.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 add_cates(self):
"""添加商品分类"""
item_name = input("请输入新商品名称:")
sql = 'insert into goods_cates(name) values ("%s")' % item_name
self.cur.execute(sql)
self.conn.commit()
def get_info_by_name(self):
"""通过名字搜索信息"""
find_name = input("请输入商品名称:")
# 通过输入" or 1=1 or "可以获取所有的商品名称,这就是sql注入,这里的引号需要和程序的引号一致,才能进行注入,' or 1=1 or '不可以
# 将name= "%s"写成name= ("%s"),也不能进行sql注入,会得到部分信息
# sql注入这一部分还需要再仔细研究一下
# sql = 'select * from goods where name= "%s";' % find_name
# self.cur.execute(sql)
# 防止sql注入的方式,将输入的字符串使用模块进行拼接
sql = 'select * from goods where name=%s;' # 注意这里的额%s不可以加引号写成"%s"
self.cur.execute(sql,[find_name]) # 注意这里的find_name是放在列表里
print(self.cur.fetchall())
@staticmethod
def print_menu():
"""功能选择"""
print("1.所有的商品")
print("2.所有的商品分类")
print("3.所有的商品品牌分类")
print("4.添加商品分类")
print("5.根据名字查询一个商品信息")
num = input("请输入功能对应的序号:")
return num
def run(self):
while True:
num = self.print_menu()
if num == "1":
# 查询所有的商品
self.show_all_items()
elif num == "2":
# 查询分类
self.show_cates()
elif num == "3":
# 查询品牌分类
self.show_brands()
elif num == "4":
# 查询品牌分类
self.add_cates()
elif num == "5":
# 查询品牌分类
self.get_info_by_name()
else:
print("输入有误,请重新输入...")
def main():
# 创建实例对象
jd = JD()
# 执行run方法
jd.run()
if __name__ == '__main__':
main()