# 1. 导图
# 2. 补充知识
## 2.1 cursor(游标)
## 2.2 cur.execute(sql_str, args=None) 与 SQL注入
### 2.2.1 什么是SQL注入
### 2.2.2 cur.execute() args参数防止SQL注入原理
### 2.2.3 cur.executemany(query,args)
## 2.3 conn.commit() / conn.rollback()
### 2.3.1 mysql中的事务
### 2.3.2 PyMySQL 中对于事务的执行 —— 巧用try…except…
# 1. 导图
---
# 2. 补充知识
## 2.1 cursor(游标)
当我们执行一个SELECt语句并LIMIT 1000,系统会一次性把1000条结果全部扔到你的面前,这时候你没有选择,你只有接受并感恩;
但如果咱有了cursor,系统会把这个1000条结果先存放起来,而 cursor 则是这个数据结构的接口,你需要数据的时候,就可以借助这个接口一行一行地取出记录(每取出一条记录,cursor就朝前移动一次,直到移动到最后一条取出结束)
--
## 2.2 cur.execute(sql_str, args=None) 与 SQL注入
### 2.2.1 什么是SQL注入
SQL注入:而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库 —— 用户提交带有恶意的数据与 SQL 进行字符串方式的拼接,得到了脱离原意的 SQL 语句,从而影响了 SQL 语句的语义,最终产生数据泄露。
sql_str = """
select * from user_table where username=
' "+userName+" ' and password=' "+password+" ';
"""
username = input("input username:")
password = input("input password:")
> input username: ' or 1 = 1 -- ;DROp DATAbase (DB Name) --
SQL注入:而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库 —— 用户提交带有恶意的数据与 SQL 进行字符串方式的拼接,得到了脱离原意的 SQL 语句,从而影响了 SQL 语句的语义,最终产生数据泄露。
sql_str = """
select * from user_table where username=
' "+userName+" ' and password=' "+password+" ';
"""
username = input("input username:")
password = input("input password:")
> input username: ' or 1 = 1 -- ;DROp DATAbase (DB Name) --
结果是:
SELECT * FROM user_table WHERe username='' or 1 = 1 ;DROp DATAbase (DB Name); --' and password=''
即,前者条件一直成立,password那里直接被注释掉,数据库就没了,寄!
-
### 2.2.2 cur.execute() args参数防止SQL注入原理
args 是 Python 内置的方法,可以对传入的参数进行校验,在一定程度上屏蔽掉SQL注入,如一些特殊符号是不能输入的,这也是为什么在很多注册的时候,#%-等符号不能输入,因为这会有SQL注入的危险,而 Python 内置方法可以规避掉一些,当然还有更多的方法,以后学到了再写!
# cur.execute(sql) 外部传参
userid = "123"
sql = """
select id,name from user where id = '%s'
""" % userid
cur.execute(sql)
# cur.execute(sql, args) 通过内置函数判断
userid = "123"
sql = """select id,name from user where id = %s and name =%s""" # 这里的%s没有''
cur.execute(sql, ('123', 'userid'))
-
### 2.2.3 cur.executemany(query,args)
能同时执行多条语句
args: 模板字符串的参数,是一个列表,列表中的每一个元素必须是元组
能同时执行多条语句
args: 模板字符串的参数,是一个列表,列表中的每一个元素必须是元组
--
## 2.3 conn.commit() / conn.rollback()
### 2.3.1 mysql中的事务
- create、select —— 隐性事务,MySQL自动commit()
(create是最开始,不会有时间混乱,它永远是时间上的前者;select不改动数据) - insert、delete、update —— 显性事务,可能会出现时间线上的冲突导致数据混乱的(就比如你转钱给我,结果你转了,系统把你余额从1000设置成了500,但还没把我从1000设置为1500的时候,就因为意外关闭了 —— 这事儿就需要一起完成,即「不可分割的」,也就是事务的定义)
-- 步骤一:禁用步骤提交功能
set autocommit = 0;
-- 步骤二:开启一个事务
start transaction;
-- 步骤三:sql语句
update table user set money=500 where name = "你";
update table user set money=1500 where name = "Shawshank_LIUYU";
-- 步骤四:结束事务
commit();
-- 如果确定我们的语句没有问题,那么我们就可以commit,如果认为我们的语句有问题,那就rollback。
### 2.3.2 PyMySQL 中对于事务的执行 —— 巧用try…except…
- create、select —— 隐性事务,MySQL自动commit()
(create是最开始,不会有时间混乱,它永远是时间上的前者;select不改动数据) - insert、delete、update —— 显性事务,可能会出现时间线上的冲突导致数据混乱的(就比如你转钱给我,结果你转了,系统把你余额从1000设置成了500,但还没把我从1000设置为1500的时候,就因为意外关闭了 —— 这事儿就需要一起完成,即「不可分割的」,也就是事务的定义)
-- 步骤一:禁用步骤提交功能 set autocommit = 0; -- 步骤二:开启一个事务 start transaction; -- 步骤三:sql语句 update table user set money=500 where name = "你"; update table user set money=1500 where name = "Shawshank_LIUYU"; -- 步骤四:结束事务 commit(); -- 如果确定我们的语句没有问题,那么我们就可以commit,如果认为我们的语句有问题,那就rollback。
### 2.3.2 PyMySQL 中对于事务的执行 —— 巧用try…except…
PyMySQL,用 commit() 让数据库知道你完成操作,对数据库产生作用,否则你的操作无效,但是查询(SELECT)例外,因为查询不需要对数据库数据进行产生修改。
import pymysql
# 打开数据库连接
db = pymysql.connect(host='localhost',
user='testuser',
password='test123',
database='TESTDB')
# 使用cursor()方法获取操作游标
cursor = db.cursor()
# SQL 插入语句
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
db.commit()
except:
# 如果发生错误则回滚
db.rollback()
# 关闭数据库连接
db.close()
---
参考文章:
Python3 MySQL 数据库连接 – PyMySQL 驱动 | 菜鸟教程



