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模塊
查:
--------------------------------------------------------------------注:如果你對python感興趣,我這有個學習Python基地,里面有很多學習資料,感興趣的+Q群:895817687 -------------------------------------------------------------------# 與數據庫建立連接 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', '123'), ('def', '123'), ('ghi', '123')]) 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 123456import 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 P
- 下一篇: MySQL 之视图、 触发器、事务、存储