Python day43 :pymysql模块/查询,插入,删除操作/SQL注入完全问题/事务/模拟登录注册服务器/视图/函数/存储过程
## pymysql模块 ```python pymysql模块 #通过pymysql跟mysqld 服务器建立连接 流程: import pymysql conn=pymysql.connect(host="localhost",user="root",password="123",dababase="db1",charset="utf8") localhost:本地主机,与"127.0.0.1"有一点不同:传输数据不需要经过网卡 cursor=conn.cursor(cursor=pymysql.cursors.DictCursor) #cursor:游标,在游标下执行sql语句. #cursor=pymysql.cursors.DictCursor,表示后面fetch取出数据的格式是字典类型(列表里面套字典) sql="select*from student where id>%s"%(12,) cursor.excute(sql) res=cursor.fetchone()#取出一条数据 res=cursor.fetchmany(10)#取出10条数据 res=cursor.fetchall()#取出所有类型 cursor.close()#关闭游标对象 conn.close()#关闭连接对象 ``` ## 插入删除操作 ```python import pymysql conn=pymysql.connect(host="localhost",user="root",password="123",database="db1",charset="utf8") cursor= conn.cursor(cursor=pymysql.cursors.DictCursor) sql="delete from t1 where id=3" cursor.execute(sql) #删除和更新的时候,需要事物提交 connn.commit() cursor.close() conn.close() ``` ## 模拟登录注册服务器编程 ```python a. 登录验证 写sql语句的时候, %传值的时候, 需要加引号: sql = "select * from t4 where name = '%s' and pwd = '%s'" % (username, pwd) 上面的sql语句带来的风险是: 例一: sername = zekai' # select * from t4 where name = 'zekai' #' and pwd = '' 例二: username = dbsahvbdsha' or 1=1 # select * from t4 where name = 'dbsahvbdsha' or 1=1 '上面出现的问题,我们称之为 SQL注入!!!' 出现问题的根源是: 因为太过于相信用户的输入, 导致我们在接受用户输入的参数的时候, 并没有对他进行转义 解决SQL注入: 1. 自己手工对用户输入的值进行转义 2. 使用execute()自动进行过滤 sql = "select * from t4 where name = %s and pwd = %s" cursor.execute(sql,(username, pwd)) # 插入一条: cursor.execute(sql, ('lxxx', '1234')) # 插入多条: data = [ ('aaaaa', 'aaa'), ('bbbb', 'bbb'), ('ffff', '666'), ('rrrr', '888'), ] cursor.executemany(sql, data) try: cursor.execute(sql, ('lxxx', '1234')) # 删除和更新的时候, 需要事物提交 conn.commit() except Exception as e: conn.rollback()#回滚 'rollback():回滚,返回到执行失败之前 ``` ```python import pymysql # 连接mysql服务器 username = input('username:') pwd = input('password:') conn = pymysql.connect(host='localhost', user='root', password='123',database='db1', charset='utf8') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select * from t4 where name = %s and pwd = %s" # 对用户输入的值进行转义 cursor.execute(sql,(username, pwd)) res = cursor.fetchone() print(res) if res: print('登录成功') else: print('登录失败') cursor.close() conn.close() ``` ## 事务: ```python 一组操作, 要么都成功, 要么都失败 特性: 原子性: 一组操作, 要么都成功, 要么都失败 一致性(Consistency):指事务发生前和发生后,数据的总额依然匹配 隔离性(Isolation):简单点说,某个事务的操作对其他事务不可见的 持久性(Durability):当事务完成后,其影响应该保留下来,不能撤消,只能通过“另开起一个事物”来抵消之前的错误 场景: 思考: 我去银行给朋友汇款, 我卡上有1000元, 朋友卡上500元, 我给朋友转账100元(无手续费), 如果,网线断了, 我的钱刚扣,而朋友的钱又没加时, 怎么办? create table t11 (id int auto_increment primary key, name varchar(32) not null default '',money int not null default 0)engine=Innodb charset=utf8; insert into t11 (name,money) values ('zekai', 1000), ('eagon', 500); 解决方法: 开启事务 (start transaction) (执行sql操作) commit : 提交上面的SQL, 让其生效 rollback: 回滚 show full tables; 显示全部类型 ``` ## 视图 ```python 视图: 产生的原因: 如果有一个SQL语句频繁的会被使用到,比如说: select * from t4 where id>12 and id <24; 搞一个映射,或者取一个别名 select * from t4 where id>12 and id <24 === > v1 视图: select * from v1; 创建视图: create view v1 as select * from t4 where id>12 and id <24; 修改视图: alter view v1 as sql语句; 删除视图: drop view v1; 问题: 如果原生的表数据发生了变化, 那视图会不会发生变化? 也会变化 视图中的数据会不会发生修改? 不会发生修改 应用场景: MySQL: (DBA) 生成视图View 程序: 调用 select * from v1; ``` ## 函数 ```python 函数: 不要轻易使用 在程序中, 用代码计算, 计算好了, 再传给SQL语句执行 ``` ## 存储过程 ```python 将一大堆 SQL 语句进行封装, 类似于函数, 结果就是存储过程 MySQL服务端:DBA (写) a. 简单的存储过程: delimiter // create procedure p1() BEGIN select * from t11; END // delimiter ; 程序: call p1(); b. 传参数: (in) delimiter // create procedure p2(in n1 int,in n2 int) BEGIN select * from t11 where id > n1; END // delimiter ; 程序: call p2(12, 2) c. 传入参数: (out) delimiter // create procedure p3(in n1 int,out n2 int) BEGIN select * from t11 where id > n1; set n2 = 1; END // delimiter ; set @v2=123212; call p3(12, @v2); select @v2; ``` ## 触发器 ```python 触发器: 向用户表中添加一条数据的同时, 在日志表中也添加一条记录 delimiter // CREATE TRIGGER t1 BEFORE INSERT ON t7 FOR EACH ROW BEGIN insert into t11 (name, money) values ('xxx', 1234); END // delimiter ; ```