zoukankan      html  css  js  c++  java
  • 48-mysql-Navicat、数据库查询题目讲解(多表操作)、python操作MySQL、sql注入问题、pymysql模块增删改查数据操作

    今日内容概要

    • navicat可视化界面操作数据库
    • 数据库查询题目讲解(多表操作)
    • python如何操作MySQL(pymysql模块)
    • sql注入问题
    • pymysql模块增删改查数据操作

    今日内容详细

    知识点补充

    # 查询平均年龄在25岁以上的部门名称
    """只要是多表查询 就有两种思路    联表    子查询"""
    # 联表操作
    	1 先拿到部门和员工表 拼接之后的结果
    	2 分析语义 得出需要进行分组
        select dep.name from emp inner join dep
        	on emp.dep_id = dep.id
            group by dep.name
            having avg(age) > 25
            ;
    	"""涉及到多表操作的时候 一定要加上表的前缀"""
    # 子查询
    	select name from dep where id in
    		(select dep_id from emp group by dep_id 
        		having avg(age) > 25);
    
    # 关键字exists(了解)
      只返回布尔值 True False
        返回True的时候外层查询语句执行
        返回False的时候外层查询语句不再执行
    	select * from emp where exists 
        	(select id from dep where id>3);
            
            
       select * from emp where exists 
        	(select id from dep where id>300);
    """
    一开始学习python的时候 下载python解释器然后直接在终端书写
    pycharm能够更加方便快捷的帮助你书写python代码
    excel word pdf
    
    我们在终端操作MySQL 也没有自动提示也无法保存等等 不方便开发
    Navicat内部封装了所有的操作数据库的命令 
    用户在使用它的时候只需要鼠标点点即可完成操作 无需书写sql语句
    """
    

    安装

    直接百度搜索 有破解版的也有非破解
    非破解的有试用期 你如果不嫌麻烦 你就用使用
    到期之后重新装再使用 或者破解一下也很简单
    https://www.cr173.com/soft/126934.html
        
    下载完成后是一个压缩包 直接解压 然后点击安装 有提醒直接点击next即可
    
    navicat能够充当多个数据库的客户端
    
    
    navicat图形化界面有时候反应速度较慢 你可以选择刷新或者关闭当前窗口再次打开即可
    
    当你有一些需求该软件无法满足的时候 你就自己动手写sql
    
    

    提示

    """
    1 MySQL是不区分大小写的
    	验证码忽略大小写
    		内部统一转大写或者小写比较即可
    			upper
    			lower
    
    2 MySQL建议所有的关键字写大写
    
    3 MySQL中的注释 有两种
    	--
    	#
    
    4 在navicat中如何快速的注释和解注释
    	ctrl + ?  加注释
    	ctrl + ?  基于上述操作再来一次就是解开注释
    	如果你的navicat版本不一致还有可能是
    	ctrl + shift + ?解开注释
    """
    

    练习题

    """
    课下一定要把握上课将的这几道题全部自己独立的理解并写出来
    
    在解决sql查询问题的时候 不要慌
    一步一步慢慢来  最终能够东拼西凑出来就过关了!!!
    
    """
    -- 1、查询所有的课程的名称以及对应的任课老师姓名
    -- SELECT
    -- 	course.cname,
    -- 	teacher.tname 
    -- FROM
    -- 	course
    -- 	INNER JOIN teacher ON course.teacher_id = teacher.tid;
    
    -- 4、查询平均成绩大于八十分的同学的姓名和平均成绩
    -- SELECT
    -- 	student.sname,
    -- 	t1.avg_num 
    -- FROM
    -- 	student
    -- 	INNER JOIN (
    -- 	SELECT
    -- 		score.student_id,
    -- 		avg( num ) AS avg_num 
    -- 	FROM
    -- 		score
    -- 		INNER JOIN student ON score.student_id = student.sid 
    -- 	GROUP BY
    -- 		score.student_id 
    -- 	HAVING
    -- 		AVG( num ) > 80 
    -- 	) AS t1 ON student.sid = t1.student_id;
    
    
    -- 7、 查询没有报李平老师课的学生姓名
    # 分步操作
    # 1 先找到李平老师教授的课程id
    # 2 再找所有报了李平老师课程的学生id
    # 3 之后去学生表里面取反 就可以获取到没有报李平老师课程的学生姓名
    -- SELECT
    -- 	student.sname 
    -- FROM
    -- 	student 
    -- WHERE
    -- 	sid NOT IN (
    -- 	SELECT DISTINCT
    -- 		score.student_id 
    -- 	FROM
    -- 		score 
    -- 	WHERE
    -- 		score.course_id IN ( SELECT course.cid FROM teacher INNER JOIN course ON teacher.tid = course.teacher_id WHERE teacher.tname = '李平老师' ) 
    -- 	);
    
    -- 8、 查询没有同时选修物理课程和体育课程的学生姓名
    --     (只要选了一门的 选了两门和没有选的都不要)
    # 1 先查物理和体育课程的id
    # 2 再去获取所有选了物理和体育的学生数据
    # 3 按照学生分组 利用聚合函数count筛选出只选了一门的学生id
    # 4 依旧id获取学生姓名
    -- SELECT
    -- 	student.sname 
    -- FROM
    -- 	student 
    -- WHERE
    -- 	student.sid IN (
    -- 	SELECT
    -- 		score.student_id 
    -- 	FROM
    -- 		score 
    -- 	WHERE
    -- 		score.course_id IN ( SELECT course.cid FROM course WHERE course.cname IN ( '物理', '体育' ) ) 
    -- 	GROUP BY
    -- 		score.student_id 
    -- 	HAVING
    -- 		COUNT( score.course_id ) = 1 
    -- 	);
    
    -- 9、 查询挂科超过两门(包括两门)的学生姓名和班级
    # 1 先筛选出所有分数小于60的数据
    # 2 按照学生分组 对数据进行计数获取大于等于2的数据
    SELECT
    	class.caption,
    	student.sname 
    FROM
    	class
    	INNER JOIN student ON class.cid = student.class_id 
    WHERE
    	student.sid IN (
    	SELECT
    		score.student_id 
    	FROM
    		score 
    	WHERE
    		score.num < 60 GROUP BY score.student_id HAVING COUNT( score.course_id ) >= 2 
    	);
    

    pymysql模块

    """
    支持python代码操作数据库MySQL
    """
    pip3 install pymysql
    

    sql注入

    """
    利用一些语法的特性 书写一些特点的语句实现固定的语法
    MySQL利用的是MySQL的注释语法
    select * from user where name='jason' -- jhsadklsajdkla' and password=''
    
    select * from user where name='xxx' or 1=1 -- sakjdkljakldjasl' and password=''
    """
    日常生活中很多软件在注册的时候都不能含有特殊符号
    因为怕你构造出特定的语句入侵数据库 不安全
    
    # 敏感的数据不要自己做拼接 交给execute帮你拼接即可
    # 结合数据库完成一个用户的登录功能?
    import pymysql
    
    
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123456',
        database = 'day48',
        charset = 'utf8'  # 编码千万不要加-
    )  # 链接数据库
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    username = input('>>>:')
    password = input('>>>:')
    sql = "select * from user where name=%s and password=%s"
    # 不要手动拼接数据 先用%s占位 之后将需要拼接的数据直接交给execute方法即可
    print(sql)
    rows = cursor.execute(sql,(username,password))  # 自动识别sql里面的%s用后面元组里面的数据替换
    if rows:
        print('登录成功')
        print(cursor.fetchall())
    else:
        print('用户名密码错误')
    

    作业布置

    """
    1 navicat自己玩一玩
    2 练习题一定要搞懂 照着我的思路一遍遍的看敲
    3 熟悉pymysql的使用
    4 sql注入产生的原因和解决方法 了解
    5 思考:如何结合mysql实现用户的注册和登录功能?
    """

    每日测验

    • 默写pymysql模块操作MySQL的代码及主要方法

    • 什么是sql注入,如何避免

      (ps:sql注入有很多种类型,我们只是介绍了其中最具代表性的一种来诠释,感兴趣的可以自己再去百度查看完整的sql注入种类及解决方式)

    内容回顾

    • Navicat软件的使用

      """
      作为开发 我们使用软件的频率较高 一般不用直接书写sql语句
      快速完成库 表的创建 等等...
      """
      
    • 数据库练习题

      """
      1 面对复杂的查询题目的时候 不要捉急 sql语句不要想着一口气写完 分步书写
      2 只要是涉及到多表查询的时候 肯定用到联表操作和子查询
      	联表操作 你可以无限制的联N多张表
      		将两张表的结果起别名 变成了一张表
      		之后再去另外一张表拼接再起别名
      		再去拼接...
      3 一定要把昨天上课将的练习题自己能够理解并敲出来
      """
      
    • pymysql模块

      # 直接安装 无需考虑版本
      pip3 install pymysql
      
      import pymysql
      
      conn = pymysql.connect(
      		host = '127.0.0.1',
          	port = 3306
          	user = 'root',
          	password = '123456',  # 还可以简写passwd = '123456'
          	database = 'db666',  # 还可以简写db = 'db666'
          	charset = 'utf8'  # 千万不要加横杆
      )
      # cursor = conn.cursor()  # 括号内不加参数的话 那么查询出来的数据是元组的形式 数据不够明确 容易混乱
      cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)  # 字典形式返回数据 数据有具体的描述信息 更加的合理方便
      
      sql = 'select * from user'
      affect_rows = cursor.execute(sql)  # 返回值是当前sql语句执行的受影响的行数
      cursor.fetchone()  # 只能结果的一条  数据本身
      cursor.fetchall()  # 拿所有		列表套多个数据
      cursor.fetchmany(n)  # 指定获取几条
      """
      上述三个方法在读取数据的时候有一个类似于文件指针的特点
      """
      cursor.scroll(1,'relative')  # 相对于光标所在的当前位置往后移动
      cursor.scroll(1,'absolute')  # 相对于数据开头往后移动
      
    • sql注入

      """
      就是利用一些特殊字符 结合软件固定的一些语句句式
      非法侵入并违规操作
      
      利用MySQL注释的语法 造成了sql注入的问题
      	用户不需要属于用户名和密码也能够登录并且获取到整个用户表的数据
      
      日常应用软件在获取用户输入的内容时 都会限制一些特殊符号的输入
      
      如何解决上述问题?
      	所有敏感的信息不要自己去做拼接操作 交互固定的模块帮你去过滤数据防止sql注入
      
      在pymysql中 execute就能够帮你过滤
      """
      # sql注入
      sql = "select * from user where username='%s' and password='%s'"%(username,password)
      # 不要自己拼接
      sql = "select * from user where username=%s and password=%s"
      execute(sql,(username,password))  # 只能识别%s
      

    pymysql补充

    # 1.针对增删改 pymysql需要二次确认才能真正的操作数据
    import pymysql
    
    
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        passwd = '123456',
        db = 'day48',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    # 增
    sql = 'insert into user(name,password) values(%s,%s)'
    # rows = cursor.execute(sql,('jackson',123))
    rows = cursor.executemany(sql,[('xxx',123),('ooo',123),('yyy',123)])
    print(rows)
    # conn.commit()  # 确认
    # 修改
    # sql = 'update user set name="jasonNB" where id=1'
    # rows = cursor.execute(sql)
    # print(rows)
    # conn.commit()  # 确认
    # 删除
    sql = 'delete from user where id=7'
    rows = cursor.execute(sql)
    print(rows)
    conn.commit()  # 确认
    # 查
    # sql = 'select * from user'
    # cursor.execute(sql)
    # print(cursor.fetchall())
    
    """
    增删改查中
        删改增它们的操作设计到数据的修改 
        需要二次确认
    """
    
    
    # 还可以一次性插入N多条数据
    rows = cursor.executemany(sql,[('xxx',123),('ooo',123)])


  • 相关阅读:
    【Selenium】Option加载用户配置,Chrom命令行参数
    Webdriver中关于driver.navigate().to()和driver.get()使用的区别
    【Selenium】idea导入eclisp项目的问题
    【数据库】数据库操作
    【monkey】
    【idea】idea快捷键
    【Selenium】Selenium1
    【Selenium】idea的selenium环境配置
    前端学习
    CSS 居中
  • 原文地址:https://www.cnblogs.com/wgwg/p/13251584.html
Copyright © 2011-2022 走看看