python中MySQL的使用

1、查询流程

  1. 创建数据库连接conn=connect(参数)
  2. 创建游标对象 cursor = conn.cursor()
  3. sql语句查询执行 count = cursor.execute(查询sql语句),返回值是查到的记录数
  4. 获取查询到的结果集result = couserfetchall()/result = couserfetchmany(参数)/result = couserfetchone()
  5. 关闭游标,cursor.close()
  6. 关闭连接对象conn.close()

2、增删改流程

  1. 创建数据库连接conn=connect(参数)
  2. 创建游标对象 cursor = conn.cursor()
  3. sql语句增删改执行 count = cursor.execute(查询sql语句),返回值是查到的记录数
  4. 连接对象提交 conn.commit()
  5. 关闭游标,cursor.close()
  6. 关闭连接对象conn.close()

注:只有当执行到commit时数据库内容才会更改,没有执行到时数据库的AUTO_INCREMENT自动增加,rollback 回滚到事务前

3、sql注入
3.1、什么是sql注入
假如 我python代码中使用如下字符串格式化后的sql语句就会造成sql注入:

name = input("请输入要查询的商品名:")
sql = '''select * from goods where name ='%s' ;'''%(name,)  #当用户输入 ' or 1=1 or ' 将会查出所有信息
count = cursor.execute(sql)
result = cursor.fetchall()
print("---------->%s<--------------------\n"%sql)
print(result)

当用户输入’ or 1=1 or '时 将把sql语句解析成如下内容:

select * from goods where name =' ' or 1=1 or ' ' ;

这样当我执行cursor.execute(sql)就表示成查询所有信息,而我本意是按照用户输入的名字查询。而不是查询所有信息。这样就容易造成信息泄露

3.2、防范sql泄露
sql语句的参数化,可以有效防止sql注入,如下:

name = input("请输入要查询的商品名:")
param = list()
param.append(name)
sql = '''select * from goods where name =%s ;'''
print("---------->%s<--------------------\n"%sql)
cursor.execute(sql,param[0])  #可以防止sql注入,在写sql时不要自己拼接sql语句
result = cursor.fetchall()

此处不同于python的字符串格式化,全部使用%s占位

4、示例代码:

import pymysql


class JD(object):
    '''JD类'''
    def __init__(self):
        '''初始化'''
        self.switch = 0
        try:
            self.conn = pymysql.connect(host = 'localhost',port = 3306,database = 'jingdong',user = 'root',password = '123456',charset = 'utf8')
            self.cursor = self.conn.cursor()
        except Exception as mysql_err:
            self.switch = 0
            print("数据库连接失败\n")
        else:
            self.switch = 1

    def __del__(self):
        if self.switch == 1:
            self.cursor.close()
            self.conn.close()
            print("连接已关闭")
        else:
            pass

    def execute_sql(self,sql):
        '''执行sql语句'''
        count = self.cursor.execute(sql)
        result = self.cursor.fetchall()
        for temp in result:
            print(temp)

    def show_all(self):
        '''显示所有商品信息'''
        sql  = 'select id as 序号,name as 商品名,cate_id as 商品类别,brand_id as 品牌,price as 价格 from goods'
        self.execute_sql(sql)   

    def show_cate(self):
        '''显示所有商品信息'''
        sql  = 'select id as 序号 ,name as 商品类别 from goods_cate'
        self.execute_sql(sql)   

    def show_brand(self):
        '''显示所有商品信息'''
        sql  = 'select id as 序号 ,name as 商品类别 from goods_brand'
        self.execute_sql(sql)   

    def get_info_by_name_no(self):
        '''不能防范sql注入'''
        name = input("请输入要查询的商品名:")
        sql = '''select * from goods where name ='%s' ;'''%(name,)  #当用户输入' or 1=1 or ' 将会查出所有信息
        print("---------->%s<--------------------\n"%sql)
        self.execute_sql(sql)

    def get_info_by_name(self):
        '''能防范sql注入'''
        name = input("请输入要查询的商品名:")
        param = list()
        param.append(name)
        sql = '''select * from goods where name =%s ;'''
        print("---------->%s<--------------------\n"%sql)
        self.cursor.execute(sql,param[0])  #可以防止sql注入,在写sql时不要自己拼接sql语句
        result = self.cursor.fetchall()
        for temp in result:
            print(temp)

    def add_brand(self):
        '''显示所有商品信息'''
        brand_name = input("请输入品牌名字:")
        sql  = '''insert into goods_brand(name) values("%s") '''%(brand_name,)
        self.cursor.execute(sql)
        self.conn.commit()


    @staticmethod
    def print_menu():
        '''打印菜单'''
        print("---------------------查询菜单-----------------")
        print("1、查询所有商品信息\n")
        print("2、查询所有商品分类\n")
        print("3、查询所有品牌分类\n")
        print("4、添加一个品牌\n")
        print("5、按名字查询一个商品,没有防范sql注入\n")
        print("6、按名字查询一个商品,有 防范sql注入\n")
        print("q、退出")
        fun_code = input("请输入查询功能码:")
        return fun_code

    def run(self):
        '''运行逻辑'''
        #print("run\n")
        while self.switch:
            fun_code = self.print_menu()
            if fun_code == "1":
                self.show_all();
            elif fun_code == "2":
                self.show_cate()
            elif fun_code == "3":
                self.show_brand()
            elif fun_code == "4":
                self.add_brand()
            elif fun_code == "5":
                self.get_info_by_name_no()
            elif fun_code == "6":
                self.get_info_by_name()
            elif fun_code == "q":
                break;
            else:
                print("输入有误,请从新输入\n")


def main():
    #1、创建JD实例对象
    jd = JD()
    #2、运行jd的run方法
    jd.run()

if __name__ == "__main__":
    main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值