SQLHelper ------ python實現


SQLHelper ------ python實現

1.第一種:

import pymysql
import threading
from DBUtils.PooledDB import PooledDB

class SqlHelper(object):
    def __init__(self):
        self.pool = PooledDB(
            creator=pymysql,  # 使用鏈接數據庫的模塊
            maxconnections=6,  # 連接池允許的最大連接數,0和None表示不限制連接數
            mincached=2,  # 初始化時,鏈接池中至少創建的鏈接,0表示不創建
            blocking=True,  # 連接池中如果沒有可用連接后,是否阻塞等待。True,等待;False,不等待然后報錯
            ping=0,
            # ping MySQL服務端,檢查是否服務可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
            host='127.0.0.1',
            port=3306,
            user='root',
            password='000000',
            database='flask_day1',
            charset='utf8'
        )
        # 用來獲取local對象
        self.local = threading.local()

    def open(self):
       	"""
       	獲取數據庫連接,游標對象
       	"""
        conn = self.pool.connection()
        cursor = conn.cursor()
        return conn,cursor

    def close(self,cursor,conn):
        """
        關閉游標,數據庫連接
        """
        cursor.close()
        conn.close()

    def __enter__(self):
        """
        with語句自動觸發,執行此方法
        """
        conn,cursor = self.open()
        rv = getattr(self.local,"stack",None)
        if not rv:
            self.local.stack = [(conn,cursor)]
        else:
            rv.append([(conn,cursor)])
            self.local.stack = rv
        return cursor

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        with語句結束時執行此方法
        """
        rv = getattr(self.local,"stack",None)
        if not rv:
            return
        conn,cursor = rv[-1]
        self.close(cursor,conn)

db = SqlHelper()

# 調用文件
import threading

def task(i):
    sql = "select * from book;"
    with db as cur:
        cur.execute(sql)
        data = cur.fetchall()
        print(i,data)

for i in range(5):
    t = threading.Thread(target=task,args=(i,))
    t.start()

說明

這個是借鑒了多線程中的threading.local()方法,當每個線程都會去獲取自己對應的數據,所以在每一個線程開啟時就會執行task方法,這個方法中有with這方法,這個方法是去調用上下文管理器,就需要執行這個對象中的__enter__()方法和__exit__() 方法;進來時執行__enter__()這個方法,並且需要又返回值,這個返回值就是with db as cur:中的cur的值,在結束的時候需要執行__exit__() 方法;在執行__enter__()方法的時候在里邊將當前這個線程的數據寫成一個字典,字典的鍵是固定的名字stack,字典的值是一個列表套元組形式,元組中是conn,cursor(數據庫連接,游標對象);將這個保存到threading.local()實例化出來的對象中self.local,在對數據庫操作完之后,with也要執行__exit__()方法,在這個方法中會使用現在的self.local對象去獲取存在這個對象中的那個字典,獲取對應的值,然后對對游標進行關閉,數據的連接進行關閉;

2.第二種:

import pymysql
import threading
from DBUtils.PooledDB import PooledDB
import greenlet


POOL = PooledDB(
            creator=pymysql,  # 使用鏈接數據庫的模塊
            maxconnections=6,  # 連接池允許的最大連接數,0和None表示不限制連接數
            mincached=2,  # 初始化時,鏈接池中至少創建的鏈接,0表示不創建
            blocking=True,  # 連接池中如果沒有可用連接后,是否阻塞等待。True,等待;False,不等待然后報錯
            ping=0,
            # ping MySQL服務端,檢查是否服務可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
            host='127.0.0.1',
            port=3306,
            user='root',
            password='000000',
            database='flask_day1',
            charset='utf8'
        )



class SqlHelper(object):
    def __init__(self):
        self.conn = None
        self.cursor = None


    def open(self):
        conn = POOL.connection()
        cursor = conn.cursor()

        return conn,cursor

    def close(self,cursor,conn):
        cursor.close()
        conn.close()

    def __enter__(self):

        self.conn,self.cursor = self.open()
        return self.cursor

    def __exit__(self, exc_type, exc_val, exc_tb):

        self.close(self.cursor,self.conn)

調用語句:

import threading

def task(i):
    sql = "select * from book;"
    with SqlHelper() as cur:
        cur.execute(sql)
        data = cur.fetchall()
        print(i,data)


for i in range(5):

    t = threading.Thread(target=task,args=(i,))
    t.start()

說明

此方法比較簡單,理解起來也比較容易,首先創建一次數據庫連接池,在SqlHelper類中只是調用執行就行,不用在重復實例化對象;每次執行sql語句是實例化SqlHelper方法就行,由於每次實例化的對象不一樣所以就不會有數據覆蓋了;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM