【學員管理系統】0x04 數據庫連接優化
阿新 • • 發佈:2018-01-30
.cn res ast exc _exit hone 聯想 文件句柄 info
【學員管理系統】0x04 pymysql數據庫連接優化
寫在前面
項目詳細需求參見:Django項目之【學員管理系統】
優化實現
把操作封裝成函數
我們之前使用pymysql操作數據庫的操作都是寫死在視圖函數中的,並且很多都是重復的代碼。
我們可以優化一下,把重復的代碼提取出來,寫成函數:
import pymysql # 定義一個數據庫相關的配置項 DB_CONFIG = { "host": "127.0.0.1", "port": 3306, "user": "root", "passwd": "root1234",code:優化"db": "mysite", "charset": "utf8" } # 查詢多條數據函數 def get_list(sql, args=None): conn = pymysql.connect( host=DB_CONFIG["host"], port=DB_CONFIG["port"], user=DB_CONFIG["user"], passwd=DB_CONFIG["passwd"], db=DB_CONFIG["db"], charset=DB_CONFIG["charset"] ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql, args) result = cursor.fetchall() cursor.close() conn.close() return result # 查詢單挑數據函數 def get_one(sql, args=None): conn = pymysql.connect( host=DB_CONFIG["host"], port=DB_CONFIG["port"], user=DB_CONFIG["user"], passwd=DB_CONFIG["passwd"], db=DB_CONFIG["db"], charset=DB_CONFIG["charset"] ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql, args) result = cursor.fetchone() cursor.close() conn.close() return result # 修改記錄 def modify(sql, args=None): conn = pymysql.connect( host=DB_CONFIG["host"], port=DB_CONFIG["port"], user=DB_CONFIG["user"], passwd=DB_CONFIG["passwd"], db=DB_CONFIG["db"], charset=DB_CONFIG["charset"] ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql, args) conn.commit() cursor.close() conn.close() # 創建記錄 def create(sql, args=None): conn = pymysql.connect( host=DB_CONFIG["host"], port=DB_CONFIG["port"], user=DB_CONFIG["user"], passwd=DB_CONFIG["passwd"], db=DB_CONFIG["db"], charset=DB_CONFIG["charset"] ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql, args) conn.commit() # 返回剛才創建的那條數據的ID last_id = cursor.lastrowid cursor.close() conn.close() return last_id
這樣只要在需要連接數據庫做操作的時候,只需要調用我們上面定義好的函數就可以了。
重用數據庫連接
但是這樣還是有問題,當我要大批量創建數據的時候,就需要多次調用create方法了,相當於多次連接多次提交。
可以繼續優化下,把數據庫的連接重用,做到只需一次連接就可執行多次操作。
class SQLManager(object): # 初始化實例方法 def __init__(self): self.conn = None self.cursor = None self.connect() # 連接數據庫 def connect(self): self.conn = pymysql.connect( host=DB_CONFIG["host"], port=DB_CONFIG["port"], user=DB_CONFIG["user"], passwd=DB_CONFIG["passwd"], db=DB_CONFIG["db"], charset=DB_CONFIG["charset"] ) self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) # 查詢多條數據 def get_list(self, sql, args=None): self.cursor.execute(sql, args) result = self.cursor.fetchall() return result # 查詢單條數據 def get_one(self, sql, args=None): self.cursor.execute(sql, args) result = self.cursor.fetchone() return result # 執行單條SQL語句 def moddify(self, sql, args=None): self.cursor.execute(sql, args) self.conn.commit() # 創建單條記錄的語句 def create(self, sql, args=None): self.cursor.execute(sql, args) self.conn.commit() last_id = self.cursor.lastrowid return last_id # 關閉數據庫cursor和連接 def close(self): self.cursor.close() self.conn.close()code:優化
把操作封裝成類
我們把我們數據庫的相關操作都封裝成一個類,在用到的時候,只需要生成一個實例,並對實例調用相應的操作方法就可以了。
db = SQLManager() class_list = db.get_list("select id, name from class") teacher_info = db.get_list("SELECT teacher.id, teacher.name, teacher2class.class_id FROM teacher LEFT JOIN teacher2class ON teacher.id = teacher2class.teacher_id WHERE teacher.id=%s;", [teacher_id]) db.close()
批量操作
但是,我如果要批量執行多個創建操作,雖然只建立了一次數據庫連接但是還是會多次提交,可不可以改成一次連接,一次提交呢?
可以,只需要用上pymysql的executemany()方法就可以了。
給我們的 SQLManager類添加一個批量執行的 multi_modify()方法就可以了。
# 執行多條SQL語句 def multi_modify(self, sql, args=None): self.cursor.executemany(sql, args) self.conn.commit()
使用with語句操作
現在我們如果一次執行多個創建操作的話就可以使用multi_modify()方法,實現一次連接一次提交了。
最後,我們每次操作完數據庫之後都要手動關閉,可不可以寫成自動關閉的呢?
聯想到我們之前學過的文件操作,使用with語句可以實現縮進結束自動關閉文件句柄的例子。
我們來把我們的數據庫連接類SQLManager類再優化下,使其支持with語句操作。
class SQLManager(object): # 初始化實例方法 def __init__(self): self.conn = None self.cursor = None self.connect() # 連接數據庫 def connect(self): self.conn = pymysql.connect( host=DB_CONFIG["host"], port=DB_CONFIG["port"], user=DB_CONFIG["user"], passwd=DB_CONFIG["passwd"], db=DB_CONFIG["db"], charset=DB_CONFIG["charset"] ) self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) # 查詢多條數據 def get_list(self, sql, args=None): self.cursor.execute(sql, args) result = self.cursor.fetchall() return result # 查詢單條數據 def get_one(self, sql, args=None): self.cursor.execute(sql, args) result = self.cursor.fetchone() return result # 執行單條SQL語句 def moddify(self, sql, args=None): self.cursor.execute(sql, args) self.conn.commit() # 執行多條SQL語句 def multi_modify(self, sql, args=None): self.cursor.executemany(sql, args) self.conn.commit() # 創建單條記錄的語句 def create(self, sql, args=None): self.cursor.execute(sql, args) self.conn.commit() last_id = self.cursor.lastrowid return last_id # 關閉數據庫cursor和連接 def close(self): self.cursor.close() self.conn.close() # 進入with語句自動執行 def __enter__(self): return self # 退出with語句塊自動執行 def __exit__(self, exc_type, exc_val, exc_tb): self.close()Code:優化
【學員管理系統】0x04 數據庫連接優化