MySQL 之Navicat Premium 12安装使用、pymysql模块使用、sql注入问题的产生与解决
本文内容提要:
Navicat Premium 12 的介绍、使用。
pymysql模块的使用
sql注入问题的产生与解决
----------------------------------------------------------------------------------------------------------------------------------------
一、Navicat Premium 12简介与使用:
/1、Navicat Premium 12是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat 是以直觉化的图形用户界面而建的,让你可以以安全并且简单的方式创建、组织、访问并共用信息。
其实Navicat Premium 12与MySQL直接的关系就相当于pycharm与python解释器之间的关系,而Navicat就是一种操作数据库图形化的一种功能加强软件。学会它的目的只有一个:更高效地让我们操作管理查询数据库
2、Navicat Premium 12的使用:(由于Navicat Premium 12主要是图形化操作界面,所以个人此处省去操作流程,具体流程都可以通过可视化的图形界面自己去摸索清楚,这是作为程序员的最基本的要求吧。)
Navicat Premium 12安装与破解方法详见:https://www.cnblogs.com/suguangti/p/10875870.html
对Navicat Premium 12的使用我们需要掌握大致以下几种:
- 测试+连接数据库
- 新建数据库
- 新建表,新增字段+类型+约束
- 设计表:外键
- 新建查询
- 读懂并会建立表模型
# Tip:批量加注释:Ctrl+? 批量去注释:Ctrl+shift+?
二、pymysql模块的使用:
pymysql的一般使用方法:import pymysql # 导入pymysql模块
查:
# 与数据库建立连接
conn = pymysql.connect(
host='localhost',
user='root',
password='******',
database='pymysql_ts',
charset='utf8'
) # 建立游标连接
# cursor = conn.cursor() # 执行完毕返回的结果,默认用元组显示
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 以字典的方式显示数据 # pymysql 操作数据库的方法:
# 执行sql语句
# ----------------------------------------------------------------------------------------------
下面是pymysql_ts数据库下的user_info表内容:
# id name password
# 1 sgt 123456
# 2 jason 123456
# 3 smoke 123456
# ----------------------------------------------------------------------------------------------
# 1、验证登陆账户密码:
'''
while True:
user = input('>>>>:').strip()
pwd = input('>>>>:').strip()
sql = "select * from user_info where name ='%s' and password ='%s'" % (user, pwd) # 这里的%s需要加引号
# sql = 'select * from user_info' # 这里的%s需要加引号
res = cursor.execute(sql) # 执行sql语句,返回sql查询成功的记录
if res:
# sql查询语句中的where条件能匹配到name和password字段,返回查询记录1,打印登陆成功后的信息
print('登陆成功') # 获取真实数据(该用户名在数据库中的记录数据)
else:
print('用户名密码错误') # where条件匹配不到数据,查询数据为空,则账号密码错误
'''
# ----------------------------------------------------------------------------------------------
sql = "select * from user_info" # sql语句,获取user_info表的所有记录
cursor.execute(sql) # 获取真实数据之前一定要执行sql语句
# ----------------------------------------------------------------------------------------------
# fetchall() 返回一个包含多个字典的列表
'''
print(cursor.fetchall()) # 获取满足where条件能查询到的所有真实数据
# 打印结果:[{'id': 1, 'name': 'sgt', 'password': '123456'},\
# {'id': 2, 'name': 'jason', 'password': '123456'}, {'id': 3, 'name': 'smoke', 'password': '123456'}]
'''
# ----------------------------------------------------------------------------------------------
# fetchone() 返回一个字典
'''
print(cursor.fetchone()) # 打印结果:{'id': 1, 'name': 'sgt', 'password': '123456'}
print(cursor.fetchone()) # 打印结果:{'id': 2, 'name': 'jason', 'password': '123456'}
print(cursor.fetchone()) # 打印结果:{'id': 3, 'name': 'smoke', 'password': '123456'}
'''
# 注意看结果,第一个id为1,后面依次是2、3,也就是说第二次获取结果是在第一次获取结果之后开始获取的,这就和前面的cursor的
# 意思不谋而合,游标连接,也就是每次获取真实数据都是按游标位置开始获取,类似于管道取值,取完一个少一个。
# 需求:如果我想每次获取数据都从最一开始获取数据,该如何实现?
# 解决方法:相对移动,绝对移动
'''
# 相对移动:
# cursor.scroll(1,'relative') # 数字1代表从当前位置移动一个记录位置
# 比如:
print(cursor.fetchone()) # 打印结果:{'id': 1, 'name': 'sgt', 'password': '123456'}
cursor.scroll(1,'relative') # 第1个记录位置已经获取完,从当前记录位置2开头向后移动1个记录位置,则下次打印就是从第3个记录位置的开头开始获取
print(cursor.fetchone()) # 打印结果:{'id': 3, 'name': 'smoke', 'password': '123456'}
'''
'''
# 绝对移动:
# cursor.scroll(1,'absolute') # 从最开头的记录位置开始数的第1个位置后也就是第2个记录位置开头开始获取数据
print(cursor.fetchone()) # 打印结果:{'id': 1, 'name': 'sgt', 'password': '123456'}
print(cursor.fetchone()) # 打印结果:{{'id': 2, 'name': 'jason', 'password': '123456'}
print(cursor.fetchone()) # 打印结果:{'id': 3, 'name': 'smoke', 'password': '123456'}
# 运行到此处全部记录全部取完
print(cursor.fetchone()) # 打印结果:None
cursor.scroll(0, 'absolute') # 游标移动到在绝对位置(最开始),0代表最开始,如果是1代表0位置向后推一个记录位置
print(cursor.fetchone()) # 打印结果:{'id': 1, 'name': 'sgt', 'password': '123456'}
'''
# ----------------------------------------------------------------------------------------------
# fetchmany(n) 指定取n个记录,返回一个n个字典数据的列表,不写n默认为1
# print(cursor.fetchmany()) # 获取满足where条件能查询到的n条真实数据,用一个包含n个字典的列表表示
# '''
print(cursor.fetchmany()) # 打印结果:[{'id': 1, 'name': 'sgt', 'password': '123456'}]
# '''
cursor.close() # 关闭游标连接
conn.close() # 断开数据库连接
增删改
# -------------------------------------------------------------------------------------------------------------
# pymysql的增删改:
# 其实就是用sursor.execute(sql)去执行sql语句,不同的就是sql语句是什么
# 先导入模块:
import pymysql
# 建立数据库连接:
conn = pymysql.connect(
host='localhost',
user='root',
password='******',
database='pymysql_ts',
charset='utf8'
)
# 这里还列出该数据库下的表user_info内容:
# id name password
# 1 sgt 123456
# 2 jason 123456
# 3 smoke 123456
# 建立游标连接(设置返回结果为字典模式)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 开始写入sql数据操作语句:
'''
user = input('输入注册用户名:').strip()
pwd = input('输入注册密码:').strip()
'''
# 还记得sql的注入导致的安全问题吗?这里不管是数据库的增删改查都要用上面的解决方法
# 方法为:sql语句字符串里面先写上不带引号的%s,传入值在cursor.execute()中传入。
# -----------------------------------------------------------------------------------
# 增(表中增加记录用insert)
'''
sql = "insert into user_info(name,password) values (%s,%s)"
# 执行sql语句:
cursor.execute(sql, (user, pwd))
# 走到这里执行execute实际是并没有真正的修改数据库,接下来需要将修改行为和结果提交到数据库才能修改生效:
conn.commit()
'''
# 此时打开Navicat软件,刷新下后,就能看到user_info表中新增了一条记录
# 结果:
# 输入注册用户名:hello
# 输入注册密码:666888
# 1 sgt 123456
# 2 jason 123456
# 3 smoke 123456
# 4 hello 666888
# -----------------------------------------------------------------------------------
# 改(表中增加记录用update)
'''
sql = "update user_info set name=%s where id=4"
cursor.execute(sql, 'world')
conn.commit()
'''
# 结果:(打开Navicat软件查看,需要刷新一下)
# 1 sgt 123456
# 2 jason 123456
# 3 smoke 123456
# 4 world 666888
# -----------------------------------------------------------------------------------
# 一次新增多行记录的方法:cursor.executemany(sql,[(),(),()])
sql = "insert into user_info(name,password) values (%s,%s)" # 插入多条,此处还是写一个(%s,%s)
cursor.executemany(sql, [('abc', ''), ('def', ''), ('ghi', '')])
conn.commit()
# 结果:
# 1 sgt 123456
# 2 jason 123456
# 3 smoke 123456
# 4 world 666888
# 5 abc 123
# 6 def 123
# 7 ghi 123
三、sql注入问题产生与解决方法:
# ----------------------------------------------------------------------------------------------
# 接下来来个sql注入引发的安全问题:
# 通过上的验证用户名密码进行登录的过程,我们可以分析出,通过pymysql连接数据库后后,实际上还是运用sql语句来操作数据库,
# 获取数据库中的记录,比如通过where条件语句来拿用户输入的name和password与数据库表中的对应字段记录进行查询,注意
# 这里是查询,看能否查询到用户输入的name和password的对应字段记录,如果有,就返回个记录个数,或者获取到该记录信息,
# 如果查询不到,就返回空,至此查询完毕。
# 所以细心的人就会发现一个bug,或者安全问题
# 我们仔细看看sql查询语句:sql = "select * from user_info where name='%s' and password='%s'" % (user,pwd)
# 这里如果在第一个%s做点手脚比如输入:xxx' or 1=1 -- dfafdafafaf
# 看不懂? 来分析下:我们知道在mysql里面--代表注释,也就是--后面的都是注释,无语句执行效果。这样就省去了密码验证,同时
# 前面xxx',这里有个单引号,为何有个单引号,我把第一个%s放进sql语句中:
# sql = "select * from user_info where name='xxx' or 1=1 -- dfafdafafaf' and password='%s'" % (user,pwd)
# ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
# 看到没有,这个select查询语句变成什么样了? select * from user_info where name='xxx' or 1=1
# 此时我们就看到上面语句结果,最后结果就是where条件1=1成立,表user_info中的全部数据都能被查询到。
# -------------------------------------------------------------------------------------------------------------
# 来一段具体代码:
# 首先在数据库pymysql_ts中有个表:
# id name password
# 1 sgt 123456
# 2 jason 123456
# 3 smoke 123456 import pymysql
# 建立数据库连接:
conn = pymysql.connect(
host='localhost',
user='root',
password='******',
database='pymysql_ts', # 找到其中一个数据库
charset='utf8'
)
# 以返回结果为字典的形式建立游标连接:
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 开始操作数据库:
user = input('输入用户名:').strip()
pwd = input('输入密码:').strip()
# 写sql语句:
'''
sql = "select * from user_info where name='%s' and password='%s'" % (user, pwd)
# 执行sql语句,返回查询的记录数
cursor.execute(sql)
# 打印获取的查询记录:
print(cursor.fetchall())
# 结果为:
# 输入用户名:ddd' or 1=1 -- dfadfafafafa
# 输入密码:
# [{'id': 1, 'name': 'sgt', 'password': '123456'}, {'id': 2, 'name': 'jason', 'password': '123456'}, \
# {'id': 3, 'name': 'smoke', 'password': '123456'}]
# 至此,这就是sql注入问题,很显然这是不安全的,也是不对的*_*,需要解决啊!
'''
# -------------------------------------------------------------------------------------------------------------
# 解决方法:将用户输入的数据交给mysql去处理
# 在写sql语句时候进行变化一下:
sql = "select * from user_info where name=%s and password=%s"
cursor.execute(sql, (user, pwd)) # 去掉上面%s的引号,将user和pwd传入execute里面,pymysql会自动识别%s自行传入数据
print(cursor.fetchall())
# 结果:
# 输入用户名:xxx' or 1=1 -- dafafafafafa
# 输入密码:fdaf
# ()
# 最后总结:为安全考虑,最好不要手动去拼接查询sql语句。
cursor.close() # 当然最后养成好习惯关闭打开的游标连接
conn.close() # 同时断开的连接的数据库
MySQL 之Navicat Premium 12安装使用、pymysql模块使用、sql注入问题的产生与解决的更多相关文章
- MySQL数据库安装与Navicat Premium 12 安装与破解
一.文件下载: MySQL:官网:https://www.mysql.com/downloads/(现在最新的是5.7版) 下载路径:"Downloads" ==>> ...
- Navicat Premium 12安装与激活
https://www.jianshu.com/p/42a33b0dda9c 若使用Navicat Premium 12.1.10.0请转至Navicat Premium 12.1.10.0安装与激活 ...
- 【转载】Navicat Premium 12安装与激活
原文地址 https://www.jianshu.com/p/5f693b4c9468#comment-20147185感谢作者的无私奉献,无意侵权,如需删除请联系我!所提供的激活文件理论支持Navi ...
- Navicat Premium 12安装与激活(亲测已成功激活)
说明:博主所提供的激活文件理论支持Navicat Premium 12.0.16 - 12.0.24简体中文64位,但已测试的版本为Navicat Premium 12.0.22.12.0.23和12 ...
- Navicat Premium 12 安装与激活
一.Navicat Premium 12下载 官方下载地址:https://www.navicat.com.cn/download/navicat-premium 百度云盘:https://pan.b ...
- Navicat Premium 12 安装 与 激活
官方简体中文下载网址:https://www.navicat.com.cn/download/navicat-premium 安装的过程....(都是中文)所以略过. 开始破解....( ...... ...
- Navicat Premium 12安装、激活
Navicat Premium 12安装 Navicat Premium 12激活
- Navicat Premium 12安装和破解
链接:https://pan.baidu.com/s/1x8AFWlJYGIl3TlbA1vX63g 提取码:9hu0 安装步骤: 1.下载好后点击navicat12018_premium_cs_x ...
- 数据库——可视化工具Navicat、pymysql模块、sql注入问题
数据库--可视化工具Navicat.pymysql模块.sql注入问题 Navicat可视化工具 Navicat是数据库的一个可视化工具,可直接在百度搜索下载安装,它可以通过鼠标"点点点&q ...
随机推荐
- (动态规划)UVA-11400:Lighting System Design
You are given the task to design a lighting system for a huge conference hall. After doing a lot of ...
- Hive_Hive的管理_远程服务
远程服务启动方式 - 端口号10000 - 启动方式: #hive --service hiveserver & 以JDBC或ODBC的程序登陆到hive中操作数据时,必须选用远程服务启动方式 ...
- 083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
给定一个排序链表,删除所有重复的元素使得每个元素只留下一个.案例:给定 1->1->2,返回 1->2给定 1->1->2->3->3,返回 1->2- ...
- Gym - 101147J Whistle's New Car 树上差分
J. Whistle's New Car time limit per test 15 seconds memory limit per test 512 megabytes input car.in ...
- JavaScript alert()函数
avaScript alert()函数 alert--弹出消息对话框(对话框中有一个OK按钮) alert,中文"提醒"的意思 alert函数语法 alert(str); aler ...
- Yii2 之 UrlManager 实践 (一)
1. enablePrettyUrl yii2默认不支持类似 http://<domain>/site/error 的url格式,需要在config.php中启用 enablePrett ...
- Java运算符——通过示例学习Java编程(6)
作者:CHAITANYA SINGH 来源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=17 运算符是表示动作的字符,例如+是表示加法的算 ...
- How To Install and Secure phpMyAdmin on Ubuntu 12.04(MySQL图形管理)
原文参考链接:https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-phpmyadmin-on-ubun ...
- CF1062D Fun with Integers
思路: 找规律. 实现: #include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { ...
- leetcode378 Kth Smallest Element in a Sorted Matrix
思路1: 使用堆. 实现: class Solution { public: int kthSmallest(vector<vector<int>>& matrix, ...